﻿namespace RLab.Visualization

open System
open System.Drawing
open System.Windows.Forms
open Microsoft.DirectX
open Microsoft.DirectX.Direct3D

open Geometry
open RLab.Programming

//concrete implementation of Robot model - SCARA

type Scara(r, elements )  = 
        inherit Robot(r, elements )
        let event = Event<string>()         
        interface IProgrammable with                
            member s.Base() = 
                event.Trigger( "Moving to base position" )
                base.GoBase()
            member s.Drive joint movement =                  
                let converted = 
                    match joint with
                    | _ as j when j <=2 -> 2.0f*pi*movement/360.0f
                    | _ -> movement
                event.Trigger( String.Format("Moving joint {0} to {1}",joint,movement) )
                base.MoveJoints (                        
                    Seq.mapi 
                        ( fun i v -> 
                            match i with
                            | _ when i = joint-1 -> converted
                            | _ -> v ) 
                        base.Posistions)
            member s.TraceEvent = 
                event.Publish

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Scara = 
    let Create (r : Renderer) =         
        let rbase = r.LoadMeshFromFile(@"base.x")
        let arm1 = r.LoadMeshFromFile(@"element1.x")
        let arm2 = r.LoadMeshFromFile(@"element2.x")
        let hand = r.LoadMeshFromFile(@"hand.x")

        let elements = [
            {Model = rbase
             Offset = O
             Joint = new Vector3( 0.0f, 700.0f, 0.0f)
             Move = Matrix.RotationY //podstawa : obród w okół osi pionowej
             Step = 0.01f
             Range = -5.0f*pi/6.0f,5.0f*pi/6.0f }

            {Model = arm1
             Offset = O
             Joint = new Vector3( 425.0f, 120.0f, 0.0f )
             Move = Matrix.RotationY //człon1 : obród w okół osi pionowej
             Step = 0.01f
             Range = -5.0f*pi/6.0f,5.0f*pi/6.0f }
            
            {Model = arm2
             Offset = O
             Joint = new Vector3( 375.0f,-120.0f, 0.0f )
             Move = fun d -> Matrix.Translation(0.0f,-d,0.0f) //człon2 : ruch pionowy narzedzia
             Step = 1.0f 
             Range = 0.0f,140.0f }
            
            {Model = hand
             Offset = O
             Joint = new Vector3( 0.0f, 0.0f, 0.0f )
             Move = fun d -> Matrix.RotationY(d) //człon3 : obrót narzedzia
             Step = 1.0f
             Range = 0.0f,0.0f } ]

        new Scara(r, elements )